#include <condition_variable>
#include <iostream>
#include <mutex>
#include <queue>
#include <thread>

// 1.逻辑实现上交替
// std::mutex mtx_num;
// static int num = 1;
// void PoorImpleman() {
//     std::thread t1([]() {
//         for (;;) {
//             {
//                 std::lock_guard<std::mutex> lock(mtx_num);
//                 if (num == 1) {
//                     std::cout << "thread A print 1....." << std::endl;
//                     num++;
//                     continue;
//                 }
//             }
//             std::this_thread::sleep_for(std::chrono::milliseconds(500));
//         }
//     });
//     std::thread t2([]() {
//         for (;;) {
//             {
//                 std::lock_guard<std::mutex> lock(mtx_num);
//                 if (num == 2) {
//                     std::cout << "thread B print 2....." << std::endl;
//                     num--;
//                     continue;
//                 }
//             }
//             std::this_thread::sleep_for(std::chrono::milliseconds(500));
//         }
//     });
//     t1.join();
//     t2.join();
// }

// 2.合理的条件变量唤醒
// std::mutex mtx_num;
// static int num = 1;
// std::condition_variable cvA;
// std::condition_variable cvB;
// void ResonableImplemention() {
//     std::thread t1([]() {
//         for (;;) {
//             std::unique_lock<std::mutex> lock(mtx_num);
//             cvA.wait(lock, []() { return num == 1; });
//             num++;
//             std::cout << "thread A print 1....." << std::endl;
//             cvB.notify_one();
//         }
//     });
//     std::thread t2([]() {
//         for (;;) {
//             std::unique_lock<std::mutex> lock(mtx_num);
//             cvB.wait(lock, []() { return num == 2; });
//             num--;
//             std::cout << "thread B print 2....." << std::endl;
//             cvA.notify_one();
//         }
//     });
//     t1.join();
//     t2.join();
// }

// 3.线程安全的queue
template <class T>
class QueueSafe {
   private:
    std::queue<T> _queue;
    std::mutex _mtx;
    std::condition_variable _cond;

   public:
    void push(T& data) {
        std::lock_guard<std::mutex> lock(_mtx);
        _queue.push(data);
        _cond.notify_one();
    }
    T pop() {
        std::lock_guard<std::mutex> lock(_mtx);
        _cond.wait(lock, [&]() { return !_queue.empty(); });
        T value = _queue.front();
        _queue.pop();
        return value;
    }
};

int main() {
    // PoorImpleman();
    // ResonableImplemention();

    return 0;
}